//
//  PlayerViewController.m
//  Civacrm
//
//  Created by 王桂敏 on 2017/3/24.
//  Copyright © 2017年 王桂敏. All rights reserved.
//

#import "PlayerViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AVKit/AVKit.h>
#import "TouchButton.h"
#import "ControlView.h"

typedef NS_ENUM(NSUInteger, Direction) {
    DirectionLeftOrRight,
    DirectionUpOrDown,
    DirectionNone
};

@interface PlayerViewController ()<AVPlayerViewControllerDelegate,TouchButtonDelegate>

@property (strong, nonatomic) AVPlayer *avPlayer;

@property (assign, nonatomic) NSTimeInterval total;

@property (strong, nonatomic) CADisplayLink *link;

@property (assign, nonatomic) NSTimeInterval lastTime;

@property (strong, nonatomic) TouchButton *button;

@property (assign, nonatomic) Direction direction;

@property (assign, nonatomic) CGPoint startPoint;

@property (assign, nonatomic) CGFloat startVB;

@property (assign, nonatomic) CGFloat startVideoRate;

@property (strong, nonatomic) MPVolumeView *volumeView;//控制音量的view

@property (strong, nonatomic) UISlider* volumeViewSlider;//控制音量

@property (assign, nonatomic) CGFloat currentRate;//当期视频播放的进度

@property (nonatomic,strong) ControlView *controlView;


@end

@implementation PlayerViewController

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    // 禁用返回手势
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
    
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = YES;
    [self switchToLandspance];
    self.edgesForExtendedLayout = UIRectEdgeTop;
    [self.navigationController.navigationBar setHidden:YES];
    
    [self showIndeterminateWithHint:@"加载中，请稍后~~"];
    
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    
    // 开启返回手势
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
    }
    [self.navigationController.navigationBar setHidden:YES];
    
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.allowRotation = NO;
    
    SEL selector = NSSelectorFromString(@"setOrientation:");
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:[UIDevice currentDevice]];
    int val = UIInterfaceOrientationLandscapeLeft;
    [invocation setArgument:&val atIndex:2];
    [invocation invoke];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self initView];
}

- (void)initView{
    
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:self.playUrl] options:nil];
    
    //请自行找链接测试
    AVPlayerItem *playItem = [AVPlayerItem playerItemWithAsset:asset];
    //初始化AVPlayer
    self.avPlayer = [[AVPlayer alloc] initWithPlayerItem:playItem];
    //设置AVPlayer关联
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
    //设置视频模式
    playerLayer.videoGravity = AVLayerVideoGravityResize;
    playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width > self.view.frame.size.height ? self.view.frame.size.width : self.view.frame.size.height, self.view.frame.size.width > self.view.frame.size.height ? self.view.frame.size.height : self.view.frame.size.width);
    //创建一个UIView与AVPlayerLayer关联
    self.playerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(playerLayer.frame), CGRectGetHeight(playerLayer.frame))];
    self.playerView.backgroundColor = [UIColor blackColor];
    [self.playerView.layer addSublayer:playerLayer];
    
    [self.view addSubview:self.playerView];
    
    //添加监听
    [playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    [playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //缓存可以播放的时候调用
//    [playItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    
    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(upadte)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    //添加自定义的Button到视频画面上
    self.button = [[TouchButton alloc] initWithFrame:playerLayer.frame];
    self.button.touchDelegate = self;
    self.button.selected = NO;
    if (!self.playUrl.length) {
        [self.button setTitle:@"视频不存在，请稍后" forState:UIControlStateNormal
         ];
        self.button.selected = YES;
    }
    [self.view addSubview:self.button];
    
    self.controlView = [[ControlView alloc] initWithDownFrame:CGRectMake(0, playerLayer.frame.size.height - 49, playerLayer.frame.size.width, 49) upFrame:CGRectMake(0, 0, playerLayer.frame.size.width, 44)];
    [self.controlView.playButton addTarget:self action:@selector(handlePlayButton:) forControlEvents:UIControlEventTouchUpInside];
    [self.controlView.prograssSlider addTarget:self action:@selector(handleProgressSliderAction:) forControlEvents:UIControlEventValueChanged];
    [self.controlView.backButton addTarget:self action:@selector(handleLeftButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.controlView.upView];
    [self.view addSubview:self.controlView.downView];
    
    
    self.volumeView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width * 9.0 / 16.0);
    
    
}

- (void)initNotification{
    //监听播放失败时
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(SBPlayerItemFailedToPlayToEndTimeNotification:) name:AVPlayerItemFailedToPlayToEndTimeNotification object:[self.avPlayer currentItem]];
}
#pragma mark - NotificationAction
- (void)SBPlayerItemFailedToPlayToEndTimeNotification:(NSNotification *)sender{
    [self hideHud];
    [self showErrorWithStatus:@"加载失败"];
}

#pragma mark - buttonAction
- (void)handlePlayButton:(UIButton *)sender{
    if(self.avPlayer.rate==0){ //说明时暂停
        sender.selected = NO;
        [self.avPlayer play];
    }else if(self.avPlayer.rate==1){//正在播放
        sender.selected = YES;
        [self.avPlayer pause];
    }
}

- (void)handleButtonAction:(UIButton *)sender{
    [self.controlView showOrHide];
}

- (void)handleProgressSliderAction:(UISlider *)sender{
    //进度
    self.currentRate = sender.value;
    [self.avPlayer seekToTime:CMTimeMakeWithSeconds(self.total * self.currentRate, 1) completionHandler:^(BOOL finished) {
        //在这里处理进度设置成功后的事情
    }];
    
}

#pragma mark - TouchButtonDelegate
#pragma mark - 开始触摸
/*************************************************************************/
- (void)touchesBeganWithPoint:(CGPoint)point {
    //记录首次触摸坐标
    self.startPoint = point;
    //检测用户是触摸屏幕的左边还是右边，以此判断用户是要调节音量还是亮度，左边是亮度，右边是音量
    if (self.startPoint.x <= self.button.frame.size.width / 2.0) {
        //亮度
        self.startVB = [UIScreen mainScreen].brightness;
    } else {
        //音/量
        self.startVB = self.volumeViewSlider.value;
    }
    //方向置为无
    self.direction = DirectionNone;
    //记录当前视频播放的进度
    CMTime ctime = self.avPlayer.currentTime;
    self.startVideoRate = ctime.value / ctime.timescale / self.total;
    
}

#pragma mark - 结束触摸
- (void)touchesEndWithPoint:(CGPoint)point {
    switch (self.direction) {
        case DirectionLeftOrRight:
        {
            [self.avPlayer seekToTime:CMTimeMakeWithSeconds(self.total * self.currentRate, 1) completionHandler:^(BOOL finished) {
                //在这里处理进度设置成功后的事情
            }];
        }
            break;
        case DirectionUpOrDown:
        {
            
        }
            break;
            
        default:
        {
            if (self.button.selected) {
        
                [self removeObserverFromPlayerItem:self.avPlayer.currentItem];
                [self.playerView removeFromSuperview];
                self.playerView = nil;
                self.avPlayer = nil;
                AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:self.playUrl] options:nil];
                
                //请自行找链接测试
                AVPlayerItem *playItem = [AVPlayerItem playerItemWithAsset:asset];
                //初始化AVPlayer
                self.avPlayer = [[AVPlayer alloc] initWithPlayerItem:playItem];
                //设置AVPlayer关联
                AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
                //设置视频模式
                playerLayer.videoGravity = AVLayerVideoGravityResize;
                playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
                //创建一个UIView与AVPlayerLayer关联
                self.playerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(playerLayer.frame), CGRectGetHeight(playerLayer.frame))];
                self.playerView.backgroundColor = [UIColor blackColor];
                [self.playerView.layer addSublayer:playerLayer];
                
                [self.view addSubview:self.playerView];
                
                //添加监听
                [playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
                [playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
            
                [self.view insertSubview:self.playerView belowSubview:self.button];
                [self showIndeterminateWithHint:@"加载中，请稍后~~"];
                
                
            } else {
                [self.controlView showOrHide];
            }
            
        }
            break;
    }
    
}

#pragma mark - 拖动
- (void)touchesMoveWithPoint:(CGPoint)point {
    //得出手指在Button上移动的距离
    CGPoint panPoint = CGPointMake(point.x - self.startPoint.x, point.y - self.startPoint.y);
    //分析出用户滑动的方向
    if (self.direction == DirectionNone) {
        if (panPoint.x >= w(20) || panPoint.x <= -w(20)) {
            //进度
            self.direction = DirectionLeftOrRight;
        } else if (panPoint.y >= h(20) || panPoint.y <= -h(20)) {
            //音量和亮度
            self.direction = DirectionUpOrDown;
        }
    }
    
    if (self.direction == DirectionNone) {
        return;
    } else if (self.direction == DirectionUpOrDown) {
        //音量和亮度
        if (self.startPoint.x <= self.button.frame.size.width / 2.0) {
            //调节亮度
            if (panPoint.y < 0) {
                //增加亮度
                [[UIScreen mainScreen] setBrightness:self.startVB + (-panPoint.y / 30.0 / 10)];
            } else {
                //减少亮度
                [[UIScreen mainScreen] setBrightness:self.startVB - (panPoint.y / 30.0 / 10)];
            }
            
        } else {
            //音量
            if (panPoint.y < 0) {
                //增大音量
                [self.volumeViewSlider setValue:self.startVB + (-panPoint.y / 30.0 / 10) animated:YES];
                if (self.startVB + (-panPoint.y / 30 / 10) - self.volumeViewSlider.value >= 0.1) {
                    [self.volumeViewSlider setValue:0.1 animated:NO];
                    [self.volumeViewSlider setValue:self.startVB + (-panPoint.y / 30.0 / 10) animated:YES];
                }
                
            } else {
                //减少音量
                [self.volumeViewSlider setValue:self.startVB - (panPoint.y / 30.0 / 10) animated:YES];
            }
        }
    } else if (self.direction == DirectionLeftOrRight ) {
        //进度
        CGFloat rate = self.startVideoRate + (panPoint.x / 30.0 / 20.0);
        if (rate > 1) {
            rate = 1;
        } else if (rate < 0) {
            rate = 0;
        }
        self.currentRate = rate;
        self.controlView.prograssSlider.value = self.currentRate;
    }
}

- (MPVolumeView *)volumeView {
    if (_volumeView == nil) {
        _volumeView  = [[MPVolumeView alloc] init];
        [_volumeView sizeToFit];
        for (UIView *view in [_volumeView subviews]){
            if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
                self.volumeViewSlider = (UISlider*)view;
                break;
            }
        }
    }
    return _volumeView;
}

- (void)upadte
{
    NSTimeInterval current = CMTimeGetSeconds(self.avPlayer.currentTime);
    
    if (current!=self.lastTime) {
        //没有卡顿
        NSLog(@"没有卡顿");
    }else{
        //卡顿了
//        NSLog(@"卡顿了");
    }
    self.lastTime = current;
    self.controlView.prograssSlider.value = self.lastTime / self.total;
    
    
    self.controlView.timeLabel.text = [NSString stringWithFormat:@"%@/%@",[self intTohhmmss:(int)self.lastTime],[self intTohhmmss:(int)self.total]];
}

//监听回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    [self hideHud];
    AVPlayerItem *playerItem = (AVPlayerItem *)object;
    if ([keyPath isEqualToString:@"loadedTimeRanges"]){
        //获取缓冲进度
        NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];
        // 获取缓冲区域
        CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];
        //开始的时间
        NSTimeInterval startSeconds = CMTimeGetSeconds(timeRange.start);
        //表示已经缓冲的时间
        NSTimeInterval durationSeconds = CMTimeGetSeconds(timeRange.duration);
        // 计算缓冲总时间
        NSTimeInterval result = startSeconds + durationSeconds;
        
        
        NSLog(@"开始:%f,持续:%f,总时间:%f", startSeconds, durationSeconds, result);
        NSLog(@"视频的加载进度是:%%%f", durationSeconds / self.total * 100);
        
    }else if ([keyPath isEqualToString:@"status"]){
        //获取播放状态
        if (playerItem.status == AVPlayerItemStatusReadyToPlay){
            NSLog(@"准备播放");
            //获取视频的总播放时长
            [self.avPlayer play];
            self.total = CMTimeGetSeconds(self.avPlayer.currentItem.duration);
            CMTime ctime = self.avPlayer.currentTime;
            CGFloat currentTimeSec = ctime.value / ctime.timescale;
            NSLog(@"当前播放时间:%f", currentTimeSec);
            [self.button setTitle:nil forState:UIControlStateNormal];
            self.button.selected = NO;
        } else{
            [self.button setTitle:@"播放失败，请点击重新加载" forState:UIControlStateNormal];
            self.button.selected = YES;
        }
    } else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){
        
    }
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
//    [playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.avPlayer pause];
    [self.avPlayer setRate:0];
    //通知:
    
    [self removeObserverFromPlayerItem:self.avPlayer.currentItem];
    [self.avPlayer replaceCurrentItemWithPlayerItem:nil];
    self.total = 0;
    [self.avPlayer.currentItem cancelPendingSeeks];
    [self.avPlayer.currentItem.asset cancelLoading];
    self.avPlayer = nil;
    [self removeObserver:self];
    [self.link invalidate];
    self.link = nil;
}
//是否可以旋转
- (BOOL)shouldAutorotate
{
    return YES;
    
}
//支持的方向
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

//强制切换
- (void)switchToLandspance{
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];//这句话是防止手动先把设备置为横屏,导致下面的语句失效.
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeRight] forKey:@"orientation"];
}


/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
